home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / powerins.c < prev    next >
C/C++ Source or Header  |  2000-05-10  |  12KB  |  478 lines

  1. /***************************************************************************
  2.  
  3.                           -= Power Instinct =-
  4.                             (C) 1993 Atlus
  5.  
  6.                 driver by    Luca Elia (eliavit@unina.it)
  7.  
  8.  
  9. Note:    if MAME_DEBUG is defined, pressing Z with:
  10.  
  11.         Q            shows layer 1
  12.         W            shows layer 2
  13.         A            shows the sprites
  14.  
  15.         Keys can be used togheter!
  16.  
  17.         [ 2 Scrolling Layers ]
  18.  
  19.         Each Layer is made of various pages of 256x256 pixels.
  20.  
  21.             [Layer 0]
  22.                 Pages:                16x2
  23.                 Tiles:                16x16x4
  24.                 Scroll:                X,Y
  25.  
  26.             [Layer 1]
  27.                 Pages:                2x1
  28.                 Tiles:                8x8x4
  29.                 Scroll:                No
  30.  
  31.         [ 256 Sprites ]
  32.  
  33.         Each sprite is made of a variable amount of 16x16 tiles.
  34.         Size can therefore vary from 16x16 (1 tile) to 256x256
  35.         (16x16 tiles)
  36.  
  37.  
  38. **************************************************************************/
  39. #include "vidhrdw/generic.h"
  40.  
  41. /* Variables that driver has access to: */
  42. unsigned char *powerins_vram_0, *powerins_vctrl_0;
  43. unsigned char *powerins_vram_1, *powerins_vctrl_1;
  44. unsigned char *powerins_vregs;
  45.  
  46. /* Variables only used here: */
  47. static struct tilemap *tilemap_0, *tilemap_1;
  48. static int flipscreen, tile_bank;
  49. static int oki_bank;
  50.  
  51.  
  52.  
  53. /***************************************************************************
  54.  
  55.                         Hardware registers access
  56.  
  57. ***************************************************************************/
  58.  
  59. READ_HANDLER( powerins_vregs_r )
  60. {
  61.     return READ_WORD(&powerins_vregs[offset]);
  62. }
  63.  
  64. WRITE_HANDLER( powerins_vregs_w )
  65. {
  66.     COMBINE_WORD_MEM(&powerins_vregs[offset],data);
  67.  
  68.     switch (offset)
  69.     {
  70.         case 0x14:    // Flipscreen
  71.             flipscreen = data & 1;
  72.             tilemap_set_flip( ALL_TILEMAPS, flipscreen?(TILEMAP_FLIPX | TILEMAP_FLIPY): 0 );
  73.             break;
  74.  
  75. //        case 0x16:    // ? always 1
  76.  
  77.         case 0x18:    // Tiles Banking (VRAM 0)
  78.             if (data != tile_bank)
  79.             {
  80.                 tile_bank = data;
  81.                 tilemap_mark_all_tiles_dirty(tilemap_0);
  82.             }
  83.             break;
  84.  
  85. //        case 0x1e:    // ? there is an hidden test mode screen (set 18ff08 to 4
  86.                     //   during test mode) that calls this: sound code (!?)
  87.  
  88.         case 0x30:    // OKI banking
  89.         {
  90.             unsigned char *RAM = memory_region(REGION_SOUND1);
  91.             int new_bank = data & 0x7;
  92.  
  93.             if (new_bank != oki_bank)
  94.             {
  95.                 oki_bank = new_bank;
  96.                 memcpy(&RAM[0x30000],&RAM[0x40000 + 0x10000*new_bank],0x10000);
  97.             }
  98.         }
  99.         break;
  100.  
  101.         case 0x3e:    // OKI data
  102.             OKIM6295_data_0_w(0,data);
  103.             break;
  104.  
  105.         default:
  106.             logerror("PC %06X - Register %02X <- %02X !\n", cpu_get_pc(), offset, data);
  107.     }
  108. }
  109.  
  110.  
  111.  
  112.  
  113. /***************************************************************************
  114.  
  115.                                     Palette
  116.  
  117. ***************************************************************************/
  118.  
  119.  
  120. WRITE_HANDLER( powerins_paletteram_w )
  121. {
  122.     /*    byte 0    byte 1    */
  123.     /*    RRRR GGGG BBBB RGBx    */
  124.     /*    4321 4321 4321 000x    */
  125.  
  126.     int oldword = READ_WORD (&paletteram[offset]);
  127.     int newword = COMBINE_WORD (oldword, data);
  128.  
  129.     int r = ((newword >> 8) & 0xF0 ) | ((newword << 0) & 0x08);
  130.     int g = ((newword >> 4) & 0xF0 ) | ((newword << 1) & 0x08);
  131.     int b = ((newword >> 0) & 0xF0 ) | ((newword << 2) & 0x08);
  132.  
  133.     palette_change_color( offset/2, r,g,b );
  134.  
  135.     WRITE_WORD (&paletteram[offset], newword);
  136. }
  137.  
  138.  
  139. /***************************************************************************
  140.  
  141.                         Callbacks for the TileMap code
  142.  
  143. ***************************************************************************/
  144.  
  145.  
  146. /***************************************************************************
  147.                           [ Tiles Format VRAM 0]
  148.  
  149. Offset:
  150.  
  151. 0.w        fedc ---- ---- ----        Color Low  Bits
  152.         ---- b--- ---- ----        Color High Bit
  153.         ---- -a98 7654 3210        Code (Banked)
  154.  
  155.  
  156. ***************************************************************************/
  157.  
  158. /* Layers are made of 256x256 pixel pages */
  159. #define TILES_PER_PAGE_X    (0x10)
  160. #define TILES_PER_PAGE_Y    (0x10)
  161. #define TILES_PER_PAGE        (TILES_PER_PAGE_X * TILES_PER_PAGE_Y)
  162.  
  163. #define DIM_NX_0            (0x100)
  164. #define DIM_NY_0            (0x20)
  165.  
  166.  
  167. static void get_tile_info_0( int tile_index )
  168. {
  169.     int code = READ_WORD(&powerins_vram_0[tile_index * 2]);
  170.     SET_TILE_INFO( 0 , (code & 0x07ff) + (tile_bank*0x800), ((code & 0xf000) >> (16-4)) + ((code & 0x0800) >> (11-4)) );
  171. }
  172.  
  173. void powerins_vram_0_w(int offset,int data)
  174. {
  175.     COMBINE_WORD_MEM(&powerins_vram_0[offset],data);
  176.     tilemap_mark_tile_dirty(tilemap_0, offset/2 );
  177. }
  178.  
  179. UINT32 powerins_get_memory_offset_0(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
  180. {
  181.     return     (col * TILES_PER_PAGE_Y) +
  182.  
  183.             (row % TILES_PER_PAGE_Y) +
  184.             (row / TILES_PER_PAGE_Y) * (TILES_PER_PAGE * 16);
  185. }
  186.  
  187.  
  188.  
  189. /***************************************************************************
  190.                           [ Tiles Format VRAM 1]
  191.  
  192. Offset:
  193.  
  194. 0.w        fedc ---- ---- ----        Color
  195.         ---- ba98 7654 3210        Code
  196.  
  197.  
  198. ***************************************************************************/
  199.  
  200. #define DIM_NX_1    (0x40)
  201. #define DIM_NY_1    (0x20)
  202.  
  203. static void get_tile_info_1( int tile_index )
  204. {
  205.     int code = READ_WORD(&powerins_vram_1[tile_index * 2]);
  206.     SET_TILE_INFO( 1 , code & 0x0fff , (code & 0xf000) >> (16-4) );
  207. }
  208.  
  209. void powerins_vram_1_w(int offset,int data)
  210. {
  211.     COMBINE_WORD_MEM(&powerins_vram_1[offset],data);
  212.     tilemap_mark_tile_dirty(tilemap_1, offset/2 );
  213. }
  214.  
  215.  
  216.  
  217.  
  218.  
  219. /***************************************************************************
  220.  
  221.  
  222.                                 Vh_Start
  223.  
  224.  
  225. ***************************************************************************/
  226.  
  227. int powerins_vh_start(void)
  228. {
  229.     tilemap_0 = tilemap_create(    get_tile_info_0,
  230.                                 powerins_get_memory_offset_0,
  231.                                 TILEMAP_OPAQUE,
  232.                                 16,16,
  233.                                 DIM_NX_0, DIM_NY_0 );
  234.  
  235.     tilemap_1 = tilemap_create(    get_tile_info_1,
  236.                                 tilemap_scan_cols,
  237.                                 TILEMAP_TRANSPARENT,
  238.                                 8,8,
  239.                                 DIM_NX_1, DIM_NY_1 );
  240.  
  241.     if (tilemap_0 && tilemap_1)
  242.     {
  243.         tilemap_set_scroll_rows(tilemap_0,1);
  244.         tilemap_set_scroll_cols(tilemap_0,1);
  245.         tilemap_0->transparent_pen = 15;
  246.  
  247.         tilemap_set_scroll_rows(tilemap_1,1);
  248.         tilemap_set_scroll_cols(tilemap_1,1);
  249.         tilemap_1->transparent_pen = 15;
  250.  
  251.         oki_bank = -1;    // samples bank "unitialised"
  252.         return 0;
  253.     }
  254.     else return 1;
  255. }
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262. /***************************************************************************
  263.  
  264.  
  265.                                 Sprites Drawing
  266.  
  267.  
  268. ***************************************************************************/
  269.  
  270.  
  271.  
  272. /* --------------------------[ Sprites Format ]----------------------------
  273.  
  274. Offset:        Format:                    Value:
  275.  
  276.     00         fedc ba98 7654 321-        -
  277.              ---- ---- ---- ---0        Display this sprite
  278.  
  279.     02         fed- ---- ---- ----        -
  280.              ---c ---- ---- ----        Flip X
  281.              ---- ba9- ---- ----        -
  282.              ---- ---8 ---- ----        Code High Bit
  283.             ---- ---- 7654 ----        Number of tiles along Y, minus 1 (1-16)
  284.             ---- ---- ---- 3210        Number of tiles along X, minus 1 (1-16)
  285.  
  286.     04                                 Unused?
  287.  
  288.     06        f--- ---- ---- ----        -
  289.             -edc ba98 7654 3210        Code Low Bits
  290.  
  291.     08                                 X
  292.  
  293.     0A                                 Unused?
  294.  
  295.     0C                                Y
  296.  
  297.     0E        fedc ba98 76-- ----        -
  298.             ---- ---- --54 3210        Color
  299.  
  300.  
  301. ------------------------------------------------------------------------ */
  302.  
  303. #define SIGN_EXTEND_POS(_var_)    {_var_ &= 0x3ff; if (_var_ > 0x1ff) _var_ -= 0x400;}
  304.  
  305. static void powerins_mark_sprite_colors(void)
  306. {
  307.     int i,col,colmask[0x100];
  308.  
  309.     unsigned int *pen_usage    =    Machine->gfx[2]->pen_usage;
  310.     int total_elements        =    Machine->gfx[2]->total_elements;
  311.     int color_codes_start    =    Machine->drv->gfxdecodeinfo[2].color_codes_start;
  312.     int total_color_codes    =    Machine->drv->gfxdecodeinfo[2].total_color_codes;
  313.  
  314.     unsigned char *source = spriteram + 0x8000;
  315.     unsigned char *finish = spriteram + 0x9000;
  316.  
  317.     int xmin = Machine->drv->visible_area.min_x;
  318.     int xmax = Machine->drv->visible_area.max_x;
  319.     int ymin = Machine->drv->visible_area.min_y;
  320.     int ymax = Machine->drv->visible_area.max_y;
  321.  
  322.     memset(colmask, 0, sizeof(colmask));
  323.  
  324.     for ( ; source < finish; source += 16 )
  325.     {
  326.         int x, y;
  327.  
  328.         int    attr    =    READ_WORD(&source[ 0x0 ]);
  329.         int    size    =    READ_WORD(&source[ 0x2 ]);
  330.         int    code    =    READ_WORD(&source[ 0x6 ]);
  331.         int    sx        =    READ_WORD(&source[ 0x8 ]);
  332.         int    sy        =    READ_WORD(&source[ 0xc ]);
  333.         int    color    =    READ_WORD(&source[ 0xe ]) % total_color_codes;
  334.  
  335.         int    dimx    =    ((size >> 0) & 0xf ) + 1;
  336.         int    dimy    =    ((size >> 4) & 0xf ) + 1;
  337.  
  338.         if (!(attr&1)) continue;
  339.  
  340.         SIGN_EXTEND_POS(sx)
  341.         SIGN_EXTEND_POS(sy)
  342.  
  343.         sx += 32;
  344.  
  345.         code = (code & 0x7fff) + ( (size & 0x0100) << 7 );
  346.  
  347.         for (x = 0 ; x < dimx*16 ; x+=16)
  348.         {
  349.             for (y = 0 ; y < dimy*16 ; y+=16)
  350.             {
  351.                 if (((sx+x+15) < xmin) || ((sx+x) > xmax) ||
  352.                     ((sy+y+15) < ymin) || ((sy+y) > ymax))    continue;
  353.  
  354.                 colmask[color] |= pen_usage[(code++) % total_elements];
  355.             }
  356.         }
  357.     }
  358.  
  359.     for (col = 0; col < total_color_codes; col++)
  360.      for (i = 0; i < 15; i++)    // pen 15 is transparent
  361.       if (colmask[col] & (1 << i)) palette_used_colors[16 * col + i + color_codes_start] = PALETTE_COLOR_USED;
  362. }
  363.  
  364.  
  365.  
  366.  
  367. static void powerins_draw_sprites(struct osd_bitmap *bitmap)
  368. {
  369.     unsigned char *source = spriteram + 0x8000;
  370.     unsigned char *finish = spriteram + 0x9000;
  371.  
  372.     int screen_w    =    Machine->drv->screen_width;
  373.     int screen_h    =    Machine->drv->screen_height;
  374.  
  375.     for ( ; source < finish; source += 16 )
  376.     {
  377.         int x,y,inc;
  378.  
  379.         int    attr    =    READ_WORD(&source[ 0x0 ]);
  380.         int    size    =    READ_WORD(&source[ 0x2 ]);
  381.         int    code    =    READ_WORD(&source[ 0x6 ]);
  382.         int    sx        =    READ_WORD(&source[ 0x8 ]);
  383.         int    sy        =    READ_WORD(&source[ 0xc ]);
  384.         int    color    =    READ_WORD(&source[ 0xe ]);
  385.  
  386.         int    flipx    =    size & 0x1000;
  387.         int    flipy    =    0;    // ??
  388.  
  389.         int    dimx    =    ((size >> 0) & 0xf ) + 1;
  390.         int    dimy    =    ((size >> 4) & 0xf ) + 1;
  391.  
  392.         if (!(attr&1)) continue;
  393.  
  394.         SIGN_EXTEND_POS(sx)
  395.         SIGN_EXTEND_POS(sy)
  396.  
  397.         /* Handle Flipscreen. Apply a global offset of 32 pixels along x too */
  398.         if (flipscreen)    {    sx = screen_w - sx - dimx*16 - 32;    flipx = !flipx;
  399.                             sy = screen_h - sy - dimy*16;        flipy = !flipy;
  400.                             code += dimx*dimy-1;            inc = -1;    }
  401.         else            {    sx += 32;                        inc = +1;    }
  402.  
  403.         code = (code & 0x7fff) + ( (size & 0x0100) << 7 );
  404.  
  405.         for (x = 0 ; x < dimx ; x++)
  406.         {
  407.             for (y = 0 ; y < dimy ; y++)
  408.             {
  409.                 drawgfx(bitmap,Machine->gfx[2],
  410.                         code,
  411.                         color,
  412.                         flipx, flipy,
  413.                         sx + x*16,
  414.                         sy + y*16,
  415.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,15);
  416.  
  417.                 code += inc;
  418.             }
  419.         }
  420.  
  421.  
  422.     }
  423. }
  424.  
  425.  
  426.  
  427.  
  428.  
  429. /***************************************************************************
  430.  
  431.  
  432.                                 Screen Drawing
  433.  
  434.  
  435. ***************************************************************************/
  436.  
  437.  
  438. void powerins_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  439. {
  440.     int layers_ctrl = -1;
  441.  
  442.     int scrollx = (READ_WORD(&powerins_vctrl_0[2])&0xff) + (READ_WORD(&powerins_vctrl_0[0])&0xff)*256;
  443.     int scrolly = (READ_WORD(&powerins_vctrl_0[6])&0xff) + (READ_WORD(&powerins_vctrl_0[4])&0xff)*256;
  444.     tilemap_set_scrollx( tilemap_0, 0, scrollx - 0x20);
  445.     tilemap_set_scrolly( tilemap_0, 0, scrolly );
  446.  
  447.     tilemap_set_scrollx( tilemap_1, 0, -0x20);    // fixed offset
  448.     tilemap_set_scrolly( tilemap_1, 0,  0x00);
  449.  
  450. #ifdef MAME_DEBUG
  451. if (keyboard_pressed(KEYCODE_Z))
  452. {
  453.     int msk = 0;
  454.  
  455.     if (keyboard_pressed(KEYCODE_Q))    msk |= 1;
  456.     if (keyboard_pressed(KEYCODE_W))    msk |= 2;
  457. //    if (keyboard_pressed(KEYCODE_E))    msk |= 4;
  458.     if (keyboard_pressed(KEYCODE_A))    msk |= 8;
  459.     if (msk != 0) layers_ctrl &= msk;
  460. }
  461. #endif
  462.  
  463.     tilemap_update(ALL_TILEMAPS);
  464.  
  465.     palette_init_used_colors();
  466.  
  467.     powerins_mark_sprite_colors();
  468.  
  469.     if (palette_recalc())    tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  470.  
  471.     tilemap_render(ALL_TILEMAPS);
  472.  
  473.     if (layers_ctrl&1)        tilemap_draw(bitmap, tilemap_0, 0);
  474.     else                    osd_clearbitmap(bitmap);
  475.     if (layers_ctrl&8)        powerins_draw_sprites(bitmap);
  476.     if (layers_ctrl&2)        tilemap_draw(bitmap, tilemap_1, 0);
  477. }
  478.